#include "spsc.h"

#include <thread>
#include <cstdint>
#include <iostream>	
#include <cstdlib>
#include <exception>
#include <fstream>
#include <cstdlib>	

using namespace rigtorp;

enum class LOGFILE_ACTION 
{
    LOGFILE_OPEN = 1,
    LOGFILE_CLOSE = 2,
    LOGFILE_WRITE = 3
};

const int fileNameSize = 256;
const int singleLogSize = 2048;

struct LogMsg {
public:
    LogMsg() {
        memset(fileName, 0, fileNameSize);
        memset(log, 0, singleLogSize);
    }

    void putMsg(LOGFILE_ACTION _action, std::string _fileName, std::string _log)
    {
        strncpy_s(fileName, _fileName.c_str(), fileNameSize);
        if (_log.size() < singleLogSize)
        {
            memcpy(log, _log.c_str(), _log.size());
        }
        else
        {
            int surplus = _log.size() - singleLogSize;
            memcpy(log, _log.c_str(), singleLogSize - 1);
            tail = (char *)malloc(surplus + 1);
            if (tail) {
                memcpy(tail, _log.c_str() + singleLogSize - 1, surplus);
            }
        }
    }

    void init()
    {
        memset(fileName, 0, fileNameSize);
        memset(log, 0, singleLogSize);
        if (tail != nullptr) {
            free(tail);
        }
    }

public:
    LOGFILE_ACTION  op;
    char fileName[fileNameSize];
    char log[singleLogSize];
    char* tail = nullptr;

    ~LogMsg() {
        if (tail != nullptr) {
            free(tail);
        }
    }
};

void test_concurrent()
{
    LogMsg *msg = new LogMsg();
    LogMsg *pmsg = nullptr;
    
    SPSCQueue<LogMsg *> q(10);

    msg->putMsg(LOGFILE_ACTION::LOGFILE_OPEN, "1.txt", "aaaaaaaaaaaaaa");
    q.emplace(msg);
    
    while (true) {
        while (!q.front())
            ;

        auto start = std::chrono::system_clock::now();
        pmsg = *q.front();
        q.pop();

        auto end = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
        std::cout << duration.count() << " ns/iter" << std::endl;
        break;
    }

}

int main(int argc, char** argv)
{
    test_concurrent();

    return 0;
}